<script setup lang="ts">
import { ref, toRefs, reactive, onMounted, watch, nextTick } from 'vue'
const props = defineProps({
  list: {
    type: Array,
    default: () => [1, 2, 3, 4, 5, 6]
  },
  current: {
    type: Number,
    default: 0
  },
  type: {
    type: String,
    default: 'left'
  },
  showNum: {
    type: Number,
    default: 1
  },
  scrollNum: {
    type: Number,
    default: 1
  },
  margin: {
    type: Number,
    default: 30
  },
  pagination: {
    type: Boolean,
    default: true
  }
})
const { list, current, type, showNum, scrollNum, margin } = toRefs(props)
const boxDom = ref()
const emit = defineEmits(['change'])
const state = reactive({
  unit: 0,
  scrollUnit: 0,
  scrollLength: 0,
  index: 0,
  list: [] as any
})
onMounted(() => {
  init(list.value)
})
watch(current, (val) => {
  state.index = val
  chnage()
})
watch(list, (val: any) => {
  init(val)
})
const init = (arr: any) => {
  state.list = arr
  let boxUnit: number = 0, itemUnit = 0, innerBox = boxDom.value.children[0], len = state.list.length;
  // 设置滚动列表
  if (type.value === 'left' || type.value === 'right') {
    boxUnit = boxDom.value.offsetWidth
  }
  if (type.value === 'top' || type.value === 'bottom') {
    boxUnit = boxDom.value.offsetHeight
  }
  itemUnit = (boxUnit - margin.value * (showNum.value - 1)) / showNum.value
  if (type.value === 'left' || type.value === 'right') {
    innerBox.style.width = len * (itemUnit + margin.value) + 'px'
    innerBox.style.height = '100%'
  }
  if (type.value === 'top' || type.value === 'bottom') {
    innerBox.style.height = len * (itemUnit + margin.value) + 'px'
  }
  state.unit = itemUnit + margin.value
  state.scrollUnit = state.unit * scrollNum.value
  state.scrollLength = (len - showNum.value) / scrollNum.value
  state.index = current.value
  nextTick(() => {
    // 设置滚动item
    let childres = Array.from(boxDom.value.children[0].children)
    childres.forEach((el: any) => {
      if (type.value === 'left') {
        el.style.width = itemUnit + 'px'
        el.style.marginRight = margin.value + 'px'
        el.style.float = 'left'
      }
      if (type.value === 'top') {
        el.style.height = itemUnit + 'px'
        el.style.marginBottom = margin.value + 'px'
      }
    })
  })
}
const chnage = () => {
  let innerBox = boxDom.value.children[0]
  if (type.value === 'left') {
    innerBox.style.transform = `translate3d(-${(state.scrollUnit * state.index)}px, 0px, 0px)`
  }
  if (type.value === 'top') {
    innerBox.style.transform = `translate3d(0px, -${(state.scrollUnit * state.index)}px, 0px)`
  }
}
const clickFn = (index: number) => {
  if ((index > 0 && state.index >= state.scrollLength) || (index < 0 && state.index <= 0)) {
    return
  }
  state.index += index
  if (state.index > state.scrollLength) {
    state.index = state.scrollLength
  }
  if (state.index < 0) {
    state.index = 0
  }
  chnage()
  emit("change", state.index);
}
defineExpose({ clickFn, init })
</script>

<template>
  <div class="scroll-wrapper" ref="boxDom">
    <div class="scroll-list">
      <div class="scroll-item" v-for="(item, index) in state.list" :key="index">
        <slot :name="index">
          <div class="scroll-inner"><img :src="item.src" :alt="item.title">
          </div>
        </slot>
      </div>
    </div>
    <div class="scroll-arrow prve" @click="clickFn(-1)" v-if="pagination"></div>
    <div class="scroll-arrow next" @click="clickFn(1)" v-if="pagination"></div>
  </div>
</template>

<style lang="scss" scoped>
.scroll {
  &-wrapper {
    position: relative;
    width: 100%;
    height: 100%;
    overflow: hidden;
  }

  &-inner {
    height: 100%;
    font-size: 30px;
    display: flex;
    justify-content: center;
    align-items: center;
    background-color: beige;

    img {
      width: 100%;
      height: 100%;
    }
  }

  &-list {
    position: relative;
    transition: 0.6s ease;
  }

  &-item {
    width: 100%;
    height: 100%;
  }

  &-arrow {
    position: absolute;
    top: 230px;
    width: 34px;
    height: 34px;
    background-color: rgba($color: #fff, $alpha: 0.6);
    transform: translateY(-17px);
    cursor: pointer;

    &.prve {
      left: 5px;

      &::after {
        border-width: 0 0 1px 1px;
      }
    }

    &.next {
      right: 5px;

      &::after {
        border-width: 1px 1px 0 0;
      }
    }

    &::after {
      content: "";
      position: absolute;
      left: 50%;
      top: 50%;
      width: 8px;
      height: 8px;
      border: solid 1px #626675;
      transform: translate(-50%, -50%) rotate(45deg);
    }

    &:hover {
      background-color: rgba($color: #fff, $alpha: 0.9);
    }
  }
}
</style>